home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
fdimg
/
oh!.2hd
/
OH!DEN_B.LZH
/
TOOLS
/
KEYWITCH
/
KW_S200.LZH
/
w20main.s
< prev
next >
Wrap
Text File
|
1995-03-20
|
24KB
|
938 lines
.include w01dos.mac
.include w02iocs.mac
.include w03const.mac
.include w04macro.mac
.include w05reloc.mac
.include w08id.mac
.include w09mes.mac
*使用できるスイッチ
* -----zyx wvutsrqp onmlkjih gfedcba-
ALLOWED_SWITCHES equ %00000001_00011101_01110110_10110010
.text
.even
********************************
*デバイスドライバの初期化ルーチン
*<a5.l:リクエストヘッダのアドレス
*>d0.l:終了コード
device_main::
movem.l d1-d7/a0-a6,-(sp)
*相対アドレッシングのためのベースレジスタの設定
lea.l base(pc),a6
*タイトル表示
moveq.l #M_CRLF,d4
bsr write_message
moveq.l #M_TITLE,d4
bsr write_message
*デバイスドライバのフラグをセットする
st.b (device_flag)r *デバイスドライバとして組み込まれた
*起動ディレクトリを設定
movea.l 18(a5),a0 *区切りは0,エンドコードは0,0
pea.l (exec_directory)r
move.l a0,-(sp)
DOS _NAMECK
addq.w #8,sp
*スタックエリアを設定
movea.l sp,a1
lea.l (stack_top)r,sp
move.l a1,-(sp)
*パラメータのアドレスを設定
*<a0.l:デバイス名とパラメータの並び(区切りは0,エンドコードは0,0)
search_param_top::
tst.b (a0)+
bne search_param_top *デバイス名を読み飛ばす
lea.l (device_params)r,a1
bra copy_params_next
copy_params_loop::
move.b #' ',(a1)+ *区切りをスペースにする
copy_params_copy::
move.b (a0)+,(a1)+
bne copy_params_copy
subq.w #1,a1
copy_params_next::
tst.b (a0)
bne copy_params_loop
clr.b (a1) *エンドコード
lea.l (device_params)r,a2
*OPT.2が押されていたら組み込みを中止する
moveq.l #M_ABORTED_BY_KEY,d4
moveq.l #$0B,d1
IOCS _BITSNS
btst.l #2,d0
bne device_error_exit *中止
*常駐しているかどうか確認する
bsr search_kept1
*パラメータの確認
* デバイスドライバの場合はパラメータがなくても組み込みます。
*<a2.l:パラメータのアドレス
bsr get_switches
*<d6.l:スイッチが1に指定されたビット=1
*<d7.l:スイッチが指定されたビット=1
*<a2.l:環境定義ファイル名の並びの先頭
moveq.l #M_UNKNOWN_SWITCH,d4
move.l d7,d0
and.l #ALLOWED_SWITCHES,d0 *使用できるスイッチだけマスクする
cmp.l d7,d0
bne device_error_exit *使用できないスイッチがあるまたはエラー
move.w d6,d0
not.w d0
and.w d7,d0
btst.l #'E'-'@',d0
bne device_error_exit *-e0が指定された
moveq.l #'r',d0
btst.l d0,d7
beq device_no_r_switch
btst.l d0,d6
beq device_no_r_switch
moveq.l #M_UNKNOWN_SWITCH,d4 *デバイスドライバは解除できない
*エラーメッセージを表示してデバイス初期化終了
device_error_exit::
bsr write_message
movea.l (sp)+,sp *スタックポインタを復元
movem.l (sp)+,d1-d7/a0-a6
move.w #$5003,d0
rts
********************************
*-rが指定されていない場合
*<d6.l:スイッチが1に指定されたビット=1
*<d7.l:スイッチが指定されたビット=1
*<a2.l:環境定義ファイル名の並びの先頭
device_no_r_switch::
*既に組み込まれていないか確認
moveq.l #M_ALREADY_EXIST,d4
cmpa.l a5,a6
bne device_error_exit *デバイスは2回以上登録できない
*スイッチを常駐部分のフラグ領域に展開する
bsr expand_switches
*無効なスイッチがないか
moveq.l #M_UNKNOWN_SWITCH,d4
tst.l d7
bne device_error_exit *無効なスイッチが指定された
*<a2.l:環境定義ファイル名の並びの先頭
tst.b (a2)
beq device_no_env_name *環境ファイル名が指定されていない
st.b (env_flag)r *ファイル名があるときは-eを省略できる
device_no_env_name::
********************************
*走行中のプログラムのメモリ管理ポインタへのハンドルを探す
bsr search_prog_hdl
tst.b (prog_flag)r
beq device_set_prog_9
tst.l d4
bmi device_error_exit
device_set_prog_9::
********************************
*環境定義ファイルを読み込む
*<a2.l:環境定義ファイル名の並びの先頭
movea.l a6,a4
bsr init_table_work *テーブルのワークを初期化
tst.b (env_flag)r
beq device_not_load
movem.l d6-d7/a4-a5,-(sp)
bsr load_environment *環境定義ファイルを読む
movem.l (sp)+,d6-d7/a4-a5
bne device_error_exit *エラーがあった
device_not_load::
********************************
*ASKを変更する
bsr keep_ask *ASKを変更する
bmi device_error_exit *変更できない
********************************
*ベクタを変更する
bsr set_spurious *Spurious Interruptを変更する
bsr change_vector *ベクタを変更する
********************************
*デバイス初期化終了
movea.l (sp)+,sp *スタックポインタを復元
movem.l (sp)+,d1-d7/a0-a6
bra device_keeper *変換テーブルを転送してデバイス初期化終了
********************************
*メインルーチン
main::
*相対アドレッシングのためのベースレジスタの設定
lea.l base(pc),a6
*タイトル表示
moveq.l #M_TITLE,d4
bsr write_message
*起動ディレクトリを設定
lea.l (prog_head-$80)r,a0 *起動ディレクトリ
lea.l (exec_directory)r,a1
copy_directory::
move.b (a0)+,(a1)+
bne copy_directory
*メモリサイズを設定
lea.l (prog_head-$F0)r,a0
lea.l prog_tail,a1 *相対アドレスでは届かない
suba.l a0,a1
movem.l a0-a1,-(sp)
DOS _SETBLOCK *必要な長さに設定する
addq.w #8,sp
moveq.l #M_MEMORY_SHORTAGE,d4
tst.l d0
bmi write_and_exit1 *メモリが不足している
*スタックエリアを設定
lea.l (stack_top)r,sp
*パラメータのアドレスを設定
addq.w #1,a2
*OPT.2が押されていたら組み込みを中止する
moveq.l #M_ABORTED_BY_KEY,d4
moveq.l #$0B,d1
IOCS _BITSNS
btst.l #2,d0
bne write_and_exit1 *中止
*常駐しているかどうか確認する
super
bsr search_kept2
user
*コマンドラインの確認
*<a2.l:パラメータのアドレス
bsr get_switches
bne exist_switches *スイッチがあるまたはエラー
moveq.l #M_USAGE,d4
tst.b (a2)
beq write_and_exit *コマンドラインに何も書かれていない
exist_switches::
*<d6.l:スイッチが1に指定されたビット=1
*<d7.l:スイッチが指定されたビット=1
*<a2.l:環境定義ファイル名の並びの先頭
moveq.l #M_UNKNOWN_SWITCH,d4
move.l d7,d0
and.l #ALLOWED_SWITCHES,d0 *使用できるスイッチだけマスクする
cmp.l d7,d0
bne usage_and_exit1 *使用できないスイッチがあるまたはエラー
move.w d6,d0
not.w d0
and.w d7,d0
btst.l #'E'-'@',d0
bne usage_and_exit1 *-e0が指定された
movea.l a5,a4
moveq.l #'r',d0
bclr.l d0,d7
beq no_r_switch *-rは指定されていない
btst.l d0,d6
beq no_r_switch *-rは指定されていない
movea.l a6,a4
tst.l d7
bne no_r_switch *-r以外のスイッチが同時に指定された
tst.b (a2)
bne no_r_switch *環境定義ファイル名が同時に指定された
********************************
*常駐を解除する
*<d6.l:スイッチが1に指定されたビット=1
*<d7.l:スイッチが指定されたビット=1
*<a2.l:環境定義ファイル名の並びの先頭
*常駐しているか確認
moveq.l #M_NOT_KEPT,d4
cmpa.l a5,a6
beq write_and_exit1 *常駐していない
moveq.l #M_OTHER_VERSION,d4
cmp.l (program_id+4)r,d5
bne write_and_exit1 *バージョンが違うので解除できない
moveq.l #M_CANNOT_RELEASE_DEVICE,d4
lea.l (device_flag)rr,a1
IOCS _B_BPEEK
tst.b d0
bne write_and_exit1 *デバイスドライバなので解除できない
*ASKの変更を復元できるどうか確かめる
tst.b (ask_flag)rr
beq not_recur_ask_1 *ASKは変更されていない
super
move.l (ask_flag_bits)rr,d0
bsr recur_ask_test *ASKの変更を復元できるかどうか確かめる
user
tst.l d4
bmi write_and_exit1 *ASKの変更を復元できない
not_recur_ask_1::
*キーボード関係を初期化する
super
move.b LEDSNS.w,d1
bsr _key_init *自分自身の何も設定されていない状態
*ベクタを復元する
lea.l (vector_table)rr,a0 *ベクタ管理テーブル
moveq.l #M_CANNOT_RELEASE,d4
moveq.l #0,d3 *ベクタがROMを指している=-1
move.l #$00FFFFFF,d2
di
move.w (a0)+,d0
release_loop_1::
bsr condrv_check *KEY_INITでCONDRVか
beq release_next *CONDRVを指しているのでスキップ
movea.w d0,a1
move.l d2,d0 *d2=$00FFFFFF
and.l (a1),d0 *現在のアドレス
cmp.l #$00FC0000,d0
blo release_not_rom *ROMではない
moveq.l #-1,d3 *ベクタがROMを指している
bra release_next *ROMなら比較せずに次へ
release_not_rom::
move.l d2,d1 *d2=$00FFFFFF
and.l 4(a0),d1 *指しているはずのアドレス
cmp.l d0,d1 *現在のアドレスと比較
bne release_error *ベクタが変更されていて解除できない
release_next::
addq.w #8,a0
move.w (a0)+,d0
bne release_loop_1
moveq.l #0,d4
lea.l (vector_table)rr,a0
move.w (a0)+,d0
release_loop_2::
movea.w d0,a1
cmpi.b #$FC,1(a1) *現在のアドレスの上から2バイト目
bhs release_vector_next *ROMならスキップ
bsr condrv_check *KEY_INITでCONDRVか
bne release_vector_go *違う
move.l (a0),6(a1) *CONDRVの元のベクタを復元する
cache_flush *キャッシュフラッシュ
bra release_vector_next
release_vector_go::
movea.w d0,a1
move.l (a0),(a1) *ベクタを復元
release_vector_next::
addq.w #8,a0
move.w (a0)+,d0
bne release_loop_2
release_error::
ei
user
tst.l d4
bmi write_and_exit1 *ベクタが変更されていて解除できない
tst.l d3
beq release_no_alart
moveq.l #M_ALART_ROM_VECTOR,d4
bsr write_message *ROMを指していた場合は警告する
release_no_alart::
*ASKの変更を復元する
tst.b (ask_flag)rr
beq not_recur_ask_2 *ASKは変更されていない
super
move.l (ask_flag_bits)rr,d0
bsr recur_ask *ASKの変更を復元する
user
clr.b (ask_flag)rr *常駐解除に失敗した場合のため
not_recur_ask_2::
*常駐部分をメモリから削除する
moveq.l #M_ALLOCATION_ERROR,d4
move.l (alloc_point)rr,d0
beq @f
move.l d0,-(sp)
DOS _MFREE
addq.w #4,sp
tst.l d0
bmi write_and_exit1 *メモリの開放に失敗した
@@: pea.l (prog_head-$100+$10)rr
DOS _MFREE
addq.w #4,sp
tst.l d0
bmi write_and_exit1 *メモリの開放に失敗した
*正常終了
moveq.l #M_RELEASED,d4
*メッセージを表示して正常終了
*<d4.w:メッセージの番号
write_and_exit:;
bsr write_message
DOS _EXIT
*メッセージと使用法を表示してエラー終了
*<d4.w:メッセージの番号
usage_and_exit1::
bsr write_message
moveq.l #M_USAGE,d4
*メッセージを表示してエラー終了
*<d4.w:メッセージの番号
write_and_exit1::
bsr write_message
move.w #1,-(sp)
DOS _EXIT2
********************************
*-rが指定されていないか、-rと同時に他のスイッチか環境定義ファイル名が指定された
*<d6.l:スイッチが1に指定されたビット=1
*<d7.l:スイッチが指定されたビット=1
*<a2.l:環境定義ファイル名の並びの先頭
*<a4.l:-rが指定されていない=a5/-rが指定された=a6
no_r_switch::
*<a2.l:環境定義ファイル名の並びの先頭
tst.b (a2)
beq no_env_name *環境ファイル名が指定されていない
st.b (env_flag)r *ファイル名があるときは-eを省略できる
no_env_name::
*既に常駐していないか確認
cmpa.l a5,a6
bne change_switches *既に常駐している
*スイッチを常駐部分のフラグ領域に展開する
bsr expand_switches
*無効なスイッチがないか
moveq.l #M_UNKNOWN_SWITCH,d4
tst.l d7
bne usage_and_exit1 *無効なスイッチが指定された
********************************
*走行中のプログラムのメモリ管理ポインタへのハンドルを探す
bsr search_prog_hdl
tst.b (prog_flag)r
beq set_prog_9
tst.l d4
bmi write_and_exit1
set_prog_9::
********************************
*環境定義ファイルを読み込む
*<a2.l:環境定義ファイル名の並びの先頭
*<a4.l:-rが指定されていない=a5/-rが指定された=a6
bsr init_table_work *テーブルのワークを初期化
tst.b (env_flag)r
beq not_load
movem.l d6-d7/a4-a5,-(sp)
bsr load_environment *環境定義ファイルを読む
movem.l (sp)+,d6-d7/a4-a5
bne write_and_exit1 *エラーがあった
not_load::
********************************
*ASKを変更する
super
bsr keep_ask *ASKを変更する
user
tst.l d4
bmi write_and_exit1 *変更できない
********************************
*ベクタを変更する
super
bsr set_spurious *Spurious Interruptを変更する
bsr change_vector *ベクタを変更する
user
********************************
*常駐終了
moveq.l #M_KEPT,d4
bsr write_message
bra keeper *変換テーブルを転送して常駐終了
********************************
*既に常駐している場合
*<d6.l:スイッチが1に指定されたビット=1
*<d7.l:スイッチが指定されたビット=1
*<a2.l:環境定義ファイル名の並びの先頭
*<a4.l:-rが指定されていない=a5/-rが指定された=a6
change_switches::
*常駐部分のバージョンの確認
moveq.l #M_OTHER_VERSION2,d4
cmp.l (program_id+4)r,d5 *バージョンチェック
bne write_and_exit1 *バージョンが違うので変更できない
********************************
*走行中のプログラムのメモリ管理ポインタへのハンドルを探す
super
bsr search_prog_hdl
user
btst.l #'P'-'@',d6
beq change_prog_hdl_9
tst.l d4
bmi write_and_exit1
change_prog_hdl_9::
********************************
*環境定義ファイルを読み込む
*<a2.l:環境定義ファイル名の並びの先頭
*<a4.l:-rが指定されていない=a5/-rが指定された=a6
super
bsr init_table_work *テーブルのワークを初期化
user
btst.l #'E'-'@',d7
beq not_load2
btst.l #'E'-'@',d6
beq not_load2
movem.l d6-d7/a4-a5,-(sp)
bsr load_environment *環境定義ファイルを読む
movem.l (sp)+,d6-d7/a4-a5
bne write_and_exit1 *エラーがあった
not_load2::
********************************
*-aは変更できる
change_ask::
btst.l #'A'-'@',d7
beq change_ask_end *-aが指定されていない
btst.l #'A'-'@',d6
beq change_ask_off *-a0
*-a1
change_ask_on::
lea.l (ask_flag)rr,a1
IOCS _B_BPEEK
tst.b d0
bne change_ask_end
*-a0から-a1にする
super
move.l (ask_flag_bits)rr,d0
bsr patch_ask_test *ASKを変更できるかどうか確かめる
bmi change_ask_on_error *変更できない
bsr patch_ask *ASKを変更する
change_ask_on_error::
user
tst.l d4
bmi write_and_exit1 *エラーあり
bra change_ask_end
*-a0
change_ask_off::
lea.l (ask_flag)rr,a1
IOCS _B_BPEEK
tst.b d0
beq change_ask_end
*-a1から-a0にする
super
move.l (ask_flag_bits)rr,d0
bsr recur_ask_test *ASKを復元できるかどうか確かめる
bmi change_ask_off_error *復元できない
bsr recur_ask *ASKを復元する
change_ask_off_error
user
tst.l d4
bmi write_and_exit1 *エラーあり
change_ask_end::
*スイッチを常駐部分のフラグ領域に展開する
* デバイスドライバの場合があるので、スーパーバイザモードで書き換える必要がある。
* 無効なスイッチがあってもリトライできない。
super
bclr.l #'E'-'@',d7
bsr expand_switches
user
*環境定義を変更する
super
bsr renew_table_work *テーブルのワークを常駐部に移動
user
*キーボード関係を初期化してから正常終了
super
move.b LEDSNS.w,d1
jsr (_key_init)rr *常駐部分のルーチンを呼ぶ
user
moveq.l #M_CHANGED,d4
bra write_and_exit
********************************
*ASKを変更する
* スーパーバイザモードで呼び出すこと。
*<a6.l:base
*>d4.l:エラーコード
keep_ask::
moveq.l #0,d4
tst.b (ask_flag)r
beq keep_ask_end *ASKを変更しない
move.l (ask_flag_bits_work)r,d0
bsr patch_ask_test *ASKを変更できるかどうか確かめる
bmi keep_ask_end *変更できない
bsr patch_ask *ASKを変更する
keep_ask_end::
tst.l d4
rts
********************************
*ベクタを変更する
* スーパーバイザモードで呼び出すこと。
* CONDRVがKEY_INITをフックしている場合はCONDRV側を変更します。
*<a6.l:base
*?d0/a0-a1
change_vector::
lea.l (vector_table)r,a0 *ベクタ管理テーブル
di
move.w (a0)+,d0
change_vector_loop::
bsr condrv_check *KEY_INITでCONDRVか
bne change_vector_go *違う
move.l 6(a1),(a0)+ *CONDRVが保存していた元のベクタ
move.l (a0)+,6(a1) *CONDRVからKeyWitchにジャンプさせる
cache_flush *キャッシュフラッシュ
bra change_vector_next
change_vector_go::
movea.w d0,a1
move.l (a1),(a0)+ *元のベクタを保存
move.l (a0)+,(a1) *新しいベクタを設定
change_vector_next::
move.w (a0)+,d0
bne change_vector_loop
ei
rts
********************************
*ベクタがKEY_INITならばCONDRVが組み込まれているか確認する
* スーパーバイザモードで呼び出すこと
*<d0.w:ベクタアドレス
*>a1.l:ベクタがKEY_INITならばそのアドレス
*>z:CONDRVならばeq,違えばne
condrv_check::
cmp.w #$0400+_KEY_INIT*4,d0
bne condrv_check_end *KEY_INIT以外
movea.w d0,a1
movea.l (a1),a1 *KEY_INITのアドレス
cmpi.l #'hmk*',-4(a1) *CONDRVチェック
bne condrv_check_end
cmpi.w #$6100,(a1) *bsr.w
bne condrv_check_end
cmpi.w #$4EF9,4(a1) *jmp ?.l
condrv_check_end::
rts
********************************
*Spurious InterruptをROM内のrteに変更する
* スーパーバイザモードで呼び出すこと。
*?d0/a0
set_spurious::
move.w #$4E73,d0 *rte
cmpi.b #$FC,SPUINT*4+1.w
blo set_spurious_rom *RAMを指している可能性がある
movea.l SPUINT*4.w,a0
cmp.w (a0),d0
beq set_spurious_end *既にROM内のrteを指している
set_spurious_rom::
lea.l $FC0000.l,a0
set_spurious_search::
cmp.w (a0)+,d0 *ROMからrteを探す
bne set_spurious_search
subq.w #2,a0
move.l a0,SPUINT*4.w
set_spurious_end::
rts
********************************
*常駐しているかどうか確認する(割り込みベクタとデバイスドライバのみ)
* スーパーバイザモードで呼び出すこと。
*<a6.l:base
*>d5.l:常駐している=常駐部分のバージョン/常駐していない=自分自身のバージョン
*>a5.l:常駐している=常駐部分のbase/常駐していない=自分自身のbase
*?d0-d1/d5/a1/a5
search_kept1::
*キー入力割り込みベクタを確認する
move.l (KEYINT*4).w,d0
and.l #$00FFFFFF,d0
movea.l d0,a5 *キー入力割り込みベクタ
lea.l base-key_int(a5),a5 *常駐部分のbase
move.l (program_id)rr,d0 *常駐部分のフラグ
cmp.l (program_id)r,d0 *フラグを比較する
bne not_kept_keyint *常駐していないかベクタが変更されている
move.l (program_id+4)rr,d5 *常駐部分のバージョン
rts
not_kept_keyint::
*先頭のNULデバイスを探す
search_nul::
move.w #'NU',d1
lea.l (prog_head)r,a5
move.l a5,d0
lea.l ($6800).w,a5 *Humanの先頭
sub.l a5,d0 *探す部分の長さ
and.l #$00FFFFFF,d0
lsr.l #1,d0
subq.l #1,d0
swap.w d0
search_nul_high_loop::
swap.w d0
search_nul_loop::
cmp.w (a5)+,d1 *1~2バイト目をチェック
dbeq d0,search_nul_loop
bne search_nul_high_next
cmpi.w #'L ',(a5) *3~4バイト目をチェック
dbeq d0,search_nul_loop
bne search_nul_high_next
cmpi.l #' ',2(a5) *5~8バイト目をチェック
dbeq d0,search_nul_loop
bne search_nul_high_next
cmpi.w #$8024,-2-4-4-2(a5) *デバイスタイプをチェック
dbeq d0,search_nul_loop
beq search_nul_found *見つかった
search_nul_high_next::
swap.w d0
dbra d0,search_nul_high_loop
bra not_kept *見つからない
search_nul_found::
lea.l -2-4-4-2-4(a5),a5 *デバイスヘッダ
*デバイスドライバを辿る
*<a5.l:先頭のNULデバイスのデバイスヘッダ
search_device_loop::
move.l device_name-prog_head(a5),d0 *デバイス名(1~4バイト目)
cmp.l (device_name)r,d0
bne search_device_next *違う
move.l device_name+4-prog_head(a5),d0 *デバイス名(5~8バイト目)
cmp.l (device_name+4)r,d0
bne search_device_next *違う
move.l program_id-prog_head(a5),d0 *常駐部分のフラグ
cmp.l (program_id)r,d0
beq search_device_found *見つかった
search_device_next::
move.l (a5),d0 *次のデバイスヘッダ
movea.l d0,a5
addq.l #1,d0
bne search_device_loop
bra not_kept *見つからない
search_device_found::
lea.l base-prog_head(a5),a5 *常駐部分のbase
move.l (program_id+4)rr,d5 *常駐部分のバージョン
rts
********************************
*常駐しているかどうか確認する(すべて確認)
* スーパーバイザモードで呼び出すこと。
* 自分自身がデバイスドライバのときは使わないこと。
*<a6.l:base
*>d5.l:常駐している=常駐部分のバージョン/常駐していない=自分自身のバージョン
*>a5.l:常駐している=常駐部分のbase/常駐していない=自分自身のbase
*?d0-d1/d5/a5
search_kept2::
bsr search_kept1 *割り込みとデバイスドライバをサーチ
cmpa.l a5,a6
bne search_kept2_end *見つかった
move.l #$00FFFFFF,d1
*手前を探す
lea.l (prog_head-$100)r,a5
bra lower_start
lower_next::
bsr search_kept2_check *確認ルーチン
lower_start::
move.l (a5),d0 *直前のメモリ管理ポインタ
bne lower_next
*先を探す
lea.l (prog_head-$100)r,a5
bra higher_start
higher_next::
bsr search_kept2_check *確認ルーチン
higher_start::
move.l 12(a5),d0 *直後のメモリ管理ポインタ
bne higher_next
*見つからない
not_kept::
movea.l a6,a5 *自分自身のbase
move.l (program_id+4)r,d5 *自分自身のバージョン
search_kept2_end::
rts
*確認ルーチン
search_kept2_check::
movea.l d0,a5
move.l 8(a5),d0 *メモリブロックのエンドアドレス
sub.l a5,d0 *メモリブロックの長さ
and.l d1,d0 *d1=$00FFFFFF
cmp.l #keep_tail-(prog_head-$100),d0
blo search_kept2_next *ブロックが短すぎる
move.l program_id-(prog_head-$100)(a5),d0 *常駐部分のフラグ
cmp.l (program_id)r,d0
bne search_kept2_next *違う
lea.l base-(prog_head-$100)(a5),a5 *常駐部分のbase
move.l (program_id+4)rr,d5 *常駐部分のバージョン
addq.w #4,sp *見つかった
search_kept2_next::
rts
********************************
*走行中のプログラムのメモリ管理ポインタへのハンドルを探す
* スーパーバイザモードで呼び出すこと。
*<a5.l:常駐部分のbase
*>d4.l:エラーコード
*?d0-d1/d4/a1
search_prog_hdl::
moveq.l #0,d4
move.l d4,(prog_hdl)rr
moveq.l #M_UNKNOWN_HUMAN,d4
move.w #_GETPDB~0,-(sp)
DOS _INTVCG
addq.w #2,sp
movea.l d0,a1 *_GETPDBの先頭
IOCS _B_WPEEK *先頭の命令を確認
cmp.w #$2079,d0 *movea.l abs.l,a0
bne search_prog_hdl_end *失敗
IOCS _B_LPEEK
move.l d0,d1
lea.l ($1c00).w,a1 *アロケート可能なメモリの上限
IOCS _B_LPEEK
cmp.l d0,d1 *念のためアクセス可能か調べる
bcc search_prog_hdl_end *失敗
DOS _VERNUM
cmp.w #$0300,d0
bcc search_prog_hdl_get3
DOS _GETPDB~0
bra search_prog_hdl_getend
search_prog_hdl_get3::
DOS _GETPDB
search_prog_hdl_getend::
movea.l d0,a0
lea.l -16(a0),a0 *自分のメモリ管理ポインタ
movea.l d1,a1
IOCS _B_LPEEK
cmp.l a0,d0 *現在のプログラムを指しているか
bne search_prog_hdl_end *失敗
move.l d1,(prog_hdl)rr *メモリ管理ポインタへのハンドル
moveq.l #0,d4
search_prog_hdl_end::
tst.l d4
rts
********************************
*スイッチを常駐部分のフラグ領域に展開する
* スーパーバイザモードで呼び出すこと。
*<d6.l:スイッチが1に指定されたビット=1
*<d7.l:スイッチが指定されたビット=1
*<a5.l:常駐部分のbase
*<a6.l:自分自身のbase
*>d7.l:無効なスイッチがない=0
*>z:無効なスイッチがない=1
*?d0-d1/d7/a0
expand_switches::
lea.l (expand_switches_table)r,a0
bra expand_switches_next
expand_switches_loop::
move.w (a0)+,d1
bclr.l d0,d7
beq expand_switches_next
btst.l d0,d6
sne.b (a5,d1.w)
expand_switches_next::
move.w (a0)+,d0
bne expand_switches_loop
tst.l d7
rts
expand_switches_table::
.dc.w 'a',ask_flag-base
.dc.w 'b',extend_flag-base
.dc.w 'c',click_flag-base
.dc.w 'd',delay_flag-base
.dc.w 'e',env_flag-base
.dc.w 'f',full_flag-base
.dc.w 'i',lock_flag-base
.dc.w 'j',joykey_flag-base
.dc.w 'l',led_flag-base
.dc.w 'm',meta_flag-base
.dc.w 'n',repeat_flag-base
.dc.w 'p',prog_flag-base
.dc.w 's',stop_flag-base
.dc.w 't',tvkey_flag-base
.dc.w 'v',view_flag-base
.dc.w 'x',exchange_flag-base
.dc.w 0
********************************
*スイッチの取得
*<a2.l:コマンドラインの先頭
*>d6.l:スイッチが1に指定されたビット=1
*>d7.l:スイッチが指定されたビット=1,エラーのときは最上位ビット=1
*>a2.l:スイッチ以外の文字列の並びの先頭アドレス
*>n:エラー=1
*>z:エラーなしでスイッチの指定がある=0
*?d0-d1/d6-d7/a1-a2
get_switches::
lea.l (get_switches_work)r,a1 *スイッチ以外の文字列のワーク
moveq.l #0,d7
moveq.l #0,d6
get_switches_loop::
move.b (a2)+,d0 *ワードの先頭の文字
beq get_switches_end *終わり
bsr is_space
beq get_switches_loop *空白
*/はスイッチと認めない
* cmp.b #'/',d0
* beq get_switches_switches
cmp.b #'-',d0
bne get_switches_name *スイッチではない
get_switches_switches::
move.b (a2)+,d0 *スイッチの文字
get_switches_alpha::
*スイッチに使える文字はアルファベットのみ
or.b #$20,d0
cmp.b #'a',d0
blo get_switches_error *無効なスイッチ
cmp.b #'z',d0
bhi get_switches_error *無効なスイッチ
move.b d0,d1 *スイッチの文字
bset.l d1,d7
bset.l d1,d6 *デフォルトは1
move.b (a2)+,d0 *スイッチの直後の文字
beq get_switches_end *終わり
bsr is_space
beq get_switches_loop *空白
cmp.b #'0',d0
beq get_switches_zero *0が指定された
cmp.b #'1',d0
beq get_switches_tail *1が指定された
*スイッチは連続して指定できる
bra get_switches_alpha
*0が指定された
get_switches_zero::
bclr.l d1,d6
get_switches_tail::
move.b (a2)+,d0 *0または1の直後の文字
beq get_switches_end *終わり
bsr is_space
beq get_switches_loop *空白
*スイッチは連続して指定できる
bra get_switches_alpha
*スイッチ以外の文字列
get_switches_name::
move.b d0,(a1)+
move.b (a2)+,d0 *ワードの次の文字
beq get_switches_end *終わり
bsr is_space
bne get_switches_name
get_switches_name_end::
clr.b (a1)+ *スイッチ以外の文字列の区切り
bra get_switches_loop
*無効なスイッチ
get_switches_error::
bset.l #31,d7 *最上位ビットを1にする
get_switches_end::
clr.b (a1)+ *スイッチ以外の文字列のエンドコード
clr.b (a1)
lea.l (get_switches_work)r,a2 *スイッチ以外の文字列のワーク
tst.l d7
rts
*空白か
*<d0.b:文字コード
*>z:空白=1
is_space::
cmp.b #' ',d0
beq is_space_end
cmp.b #9,d0
is_space_end::
rts
.bss
********************************
*起動ディレクトリ
exec_directory::
.ds.b 92 *_NAMECKバッファなので91バイト以上必要
********************************
*デバイスドライバのパラメータの文字列
device_params::
.ds.b 260 *区切りは空白
********************************
*環境定義ファイル名の並び
get_switches_work::
.ds.b 260 *区切りは0,エンドコードは0,0
********************************
*常駐部分が使わない各種フラグ
env_flag::
.dc.b 0 *環境定義ファイルを読み込む=-1
view_flag::
.dc.b 0 *状態を表示する=-1
********************************
*スタックエリア
.even
.ds.b 8*1024
stack_top::
.end main